package dk.seqSite.drupalBridge {
	import dk.dashboardFP.dfpLogger.DFPLogger;
	import dk.dashboardFP.dfpLogger.DFPLoggerLevels;
	import dk.seqSite.SeqSiteBase;
	import dk.seqSite.SeqSiteBaseEvent;
	import dk.seqSite.SeqSiteInitOptions;
	import dk.seqSite.TemplateRegistry;
	import dk.seqSite.tree.TreeNode;

	import nl.dpdk.services.gephyr.DrupalEvent;
	import nl.dpdk.services.gephyr.DrupalService;

	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.EventDispatcher;

	/**
	 * @author josef
	 */
	public class DrupalBridge extends EventDispatcher {

		private static var _oInstance : DrupalBridge;
		private static var _bCreatingInstance : Boolean = false;
		public static const LOGGER_GROUP : int = 550;
		private var _oSeqSite : SeqSiteBase;
		private var _doStage : Stage;
		private var _sprPageContainer : Sprite;
		private var _oInitOptions : SeqSiteInitOptions;
		private var service : DrupalService;
		private var _gateway : String;
		private var _siteTreeView : String;
		private var _requireSession : Boolean;
		private var _key : String;
		private var _domain : String;
		private var _homeUrlSegment : String;

		public function DrupalBridge() {
			if( !_bCreatingInstance ) throw new Error("Singleton and can only be accessed through DrupalBridge.get_oInstance()");
			
			setup();
		}

		private function setup() : void {
			
			//:::::::
			// dfplogger 
			DFPLogger.getLogGroupById(DrupalBridge.LOGGER_GROUP).uintColor = 0x234FFF;
			DFPLogger.getLogGroupById(DrupalBridge.LOGGER_GROUP).sLabel = "SeqSite Drupal Bridge";
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// init
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

		public function registerSeqSiteForInit(oSeqSite : SeqSiteBase, doStage : Stage, sprPageContainer : Sprite, oInitOptions : SeqSiteInitOptions) : void {

			if (oSeqSite.bInitDone) {
				throw new Error("Init must not be performed when registering SeqSiteBase to DrupalBridge. Use ConnectAndInitBridge() in DrupalBridge");
			}
			
			_oInitOptions = oInitOptions;
			_sprPageContainer = sprPageContainer;
			_doStage = doStage;
			_oSeqSite = oSeqSite;
		}

		public function connectAndInitBridge(gateway : String, siteTreeView : String, homeUrlSegment : String = "home", requireSession : Boolean = false, key : String = '', domain : String = '') : void {
			
			_homeUrlSegment = homeUrlSegment;
			_domain = domain;
			_key = key;
			_requireSession = requireSession;
			_siteTreeView = siteTreeView;
			_gateway = gateway;
			
			//:::::::
			// init framework
			_oSeqSite.bStartTreeControlWhenReady = false;
			_oSeqSite.addEventListener(SeqSiteBaseEvent.READY, onSeqSiteReady, false, 0, true);
			_oSeqSite.initSystem(_doStage, _sprPageContainer, _oInitOptions);
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// build node tree and dispatch treeCreated event
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

		private function buildNodeTree(nodeCollection : Array) : void {
			
			var nodeHolder : Object = {};
			var node : Object;
			var rootNode : Object;
			
			for each (node in nodeCollection) {
				
				//:::::::
				// place in holder 
				nodeHolder[node.nid] = node;
				node.subnodes = [];
				
				//:::::::
				// find rootnode 
				if (node.path == _homeUrlSegment) {
					rootNode = node;
				}
			}
			
			for each (node in nodeCollection) {
				if (node.parent == 0 && node != rootNode) {
					rootNode.subnodes.push(node);
				} else if (node.parent != 0) {
					nodeHolder[node.parent].subnodes.push(node);
				}
			}
			
			//:::::::
			// config rootnode 
			_oSeqSite.oRootNode.oTreeNodeData.cPageTemplate = TemplateRegistry.get_oInstance().get_cPageClassRefrenceFromAlias(rootNode.type);
			_oSeqSite.oRootNode.oTreeNodeData.sTitle = rootNode.title;
			_oSeqSite.oRootNode.oTreeNodeData.sDataRef = rootNode.nid;
			
			//:::::::
			// generate tree 
			createTreeNodeFromDrupalNode(rootNode, _oSeqSite.oRootNode);
			
			//:::::::
			// dispatch bridge ready 
			dispatchEvent(new DrupalBridgeEvent(DrupalBridgeEvent.TREE_CREATED));
		}

		private function createTreeNodeFromDrupalNode(node : Object, oTN : TreeNode) : void {
			
			var path : String;
			var segments : Array = [];
			var subTreeNode : TreeNode;
			
			for each (var subNode : Object in node.subnodes) {
				
				segments = subNode.path.split("/");
				path = segments[segments.length - 1];
				
				subTreeNode = oTN.createSubNode(path, TemplateRegistry.get_oInstance().get_cPageClassRefrenceFromAlias(subNode.type), subNode.title);
				subTreeNode.oTreeNodeData.sDataRef = subNode.nid;
				
				createTreeNodeFromDrupalNode(subNode, subTreeNode);
			}
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// connect drupal
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

		private function onSeqSiteReady(event : SeqSiteBaseEvent) : void {
			
			//constructor, takes a gateway, whether we need sessions (optional), and a key and domain (optional)
			service = new DrupalService(_gateway, _requireSession, _key, _domain);
 
			//the generic error event
			service.addEventListener(DrupalEvent.ERROR, onError);
			
			//some other error events, mapped to the same handler for demo purposes
			service.addEventListener(DrupalEvent.ERROR_SYSTEM_CONNECT, onError);
			service.addEventListener(DrupalEvent.ERROR_NODE_GET, onError);
			service.addEventListener(DrupalEvent.ERROR_USER_LOGIN, onError);
			
			//the event handlers for succesful calls
			service.addEventListener(DrupalEvent.SYSTEM_CONNECT, onConnect);
			service.addEventListener(DrupalEvent.USER_LOGIN, onUserLogin);
			service.addEventListener(DrupalEvent.VIEWS_GET, onViewGet);
 
			//since we use a session, connect to the system first, DrupalService will store the sessionId for you.
			service.systemConnect();
		}

		private function onViewGet(event : DrupalEvent) : void {
			DFPLogger.log("sitetree view :: ", event.getData(), LOGGER_GROUP);
			buildNodeTree(event.getData());
		}

		private function onConnect(event : DrupalEvent) : void {
			DFPLogger.log("onConnect, sessionId: " + service.getSessionId(), null, LOGGER_GROUP);
			service.viewsGet("sitetree", ["nid", "parent", "path", "title", "type", "field_structure_only"]);
		}

		private function onUserLogin(event : DrupalEvent) : void {
			DFPLogger.log("userLogin " + event.getData(), null, LOGGER_GROUP);
		}

		//generic error event handler
		private function onError(event : DrupalEvent) : void {
			DFPLogger.log("Error :: " + event.getError(), null, LOGGER_GROUP, DFPLoggerLevels.ERROR);
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// singleton
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

		public static function get oInstance() : DrupalBridge {
			if (!_oInstance) {
				_bCreatingInstance = true;
				_oInstance = new DrupalBridge();
				_bCreatingInstance = false;
			}
			return _oInstance;
		}
	}
}
